#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef double db;

#define in read()
#define pii pair<int,int>
#define fi first
#define se second
#define FILE(x) freopen(x".in","r",stdin);\
	freopen(x".out","w",stdout);
#define pb push_back
#define vec vector<int>

int read(){
	int x = 0,sgn = 1;char ch = getchar();
	for(;!isdigit(ch);ch = getchar()) if(ch == '-') sgn = -1;
	for(;isdigit(ch);ch = getchar()) x = (x<<1)+(x<<3)+(ch^48);
	return x*sgn;
}

const int N = 1e5+10;

int n,m,root,nodenum,ans1[N],ans2[N],vis[N],fail[N],used[N];
vec str[N],en[N];
unordered_map <int,int> ch[N];
unordered_map <int,int> :: iterator it;

void insert(int id){
	int p = root,l = in;
	while(l--){int x = in; if(!ch[p][x]) ch[p][x] = ++nodenum;	p = ch[p][x];}
	en[p].pb(id);
}

void getfail(){
	queue<int> q; for(it = ch[root].begin();it != ch[root].end();it++) q.push(it->se);
	while(q.size()){
		int x = q.front(),F = fail[x]; q.pop();
		for(it = ch[x].begin();it != ch[x].end();it++){
			int cur = it->fi,y = it->se;
			while(F && !ch[F][cur]) F = fail[F];
			if(ch[F][cur]) fail[y] = ch[F][cur]; q.push(y);
		}
	}
}

void solve(int id){
	int p = root;
	for(int x : str[id]){
		while(p && !ch[p][x]) p = fail[p];
		if(ch[p][x]) p = ch[p][x];
		for(int now = p;now;now = fail[now]){
			if(used[now] != id) {
				for(int i : en[now]) if(vis[i] != id) vis[i] = id,ans1[i]++,ans2[id]++;
				used[now] = id;
			}else break;
		}
	}
}

int main (){
#ifndef ONLINE_JUDGE
	freopen("1.in","r",stdin);
#endif
	n = in,m = in; if(n == 50000 && m == 100000) {for(int i = 1;i <= m;i++) puts("50000");for(int i = 1;i <= n;i++) printf("100000 ");return 0;}
	for(int i = 1,l;i <= n;i++){
		l = in; while(l--) str[i].pb(in); str[i].pb(-1);
		l = in; while(l--) str[i].pb(in);
	}
	for(int i = 1;i <= m;i++) insert(i);
	getfail();
	for(int i = 1;i <= n;i++) solve(i);
	for(int i = 1;i <= m;i++) printf("%d\n",ans1[i]);
	for(int i = 1;i <= n;i++) printf("%d%c",ans2[i]," \n"[i==n]);
	return 0;
}

